# -*- coding: utf-8 -*-
"""
日志结构化模块
负责将日志数据转换为结构化格式
"""

import re
import json
from typing import Dict, Any, List, Optional, Tuple
from datetime import datetime
from common.logger import get_logger
from common.utils import parse_timestamp, format_timestamp

logger = get_logger(__name__)


class LogStructurer:
    """日志结构化器"""
    
    def __init__(self):
        """初始化日志结构化器"""
        # 常见日志格式的正则表达式
        self.log_patterns = {
            'standard': re.compile(
                r'^(\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}:\d{2}(?:\.\d+)?)\s+(\w+)\s+\[([^\]]+)\]\s+(.+)$'
            ),
            'simple': re.compile(
                r'^(\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}:\d{2})\s+(\w+)\s+(.+)$'
            ),
            'json': re.compile(r'^\{.*\}$'),
            'nginx': re.compile(
                r'^(\S+)\s+-\s+-\s+\[([^\]]+)\]\s+"([^"]*)"\s+(\d+)\s+(\d+)\s+"([^"]*)"\s+"([^"]*)"'
            ),
            'apache': re.compile(
                r'^(\S+)\s+-\s+-\s+\[([^\]]+)\]\s+"([^"]*)"\s+(\d+)\s+(\d+)'
            )
        }
        
        # 字段映射配置
        self.field_mapping = {
            'timestamp': ['@timestamp', 'timestamp', 'time', 'date'],
            'level': ['level', 'severity', 'log_level', 'priority'],
            'message': ['message', 'msg', 'content', 'text'],
            'app_name': ['app_name', 'application', 'service', 'component'],
            'host': ['host', 'hostname', 'server', 'node'],
            'source': ['source', 'logger', 'class', 'module']
        }
    
    def structure_log(self, log_data: Dict[str, Any]) -> Dict[str, Any]:
        """
        结构化单条日志
        
        Args:
            log_data: 原始日志数据
            
        Returns:
            结构化后的日志数据
        """
        try:
            structured_log = log_data.copy()
            
            # 解析消息内容
            if 'message' in structured_log:
                parsed_fields = self._parse_message(structured_log['message'])
                structured_log.update(parsed_fields)
            
            # 标准化字段
            structured_log = self._normalize_fields(structured_log)
            
            # 解析时间戳
            if 'timestamp' in structured_log:
                structured_log['parsed_timestamp'] = self._parse_timestamp_field(structured_log['timestamp'])
            
            # 添加结构化标记
            structured_log['structured'] = True
            structured_log['structure_timestamp'] = self._get_current_timestamp()
            
            return structured_log
            
        except Exception as e:
            logger.error(f"结构化日志失败: {e}")
            return log_data
    
    def structure_logs(self, logs: List[Dict[str, Any]]) -> List[Dict[str, Any]]:
        """
        批量结构化日志
        
        Args:
            logs: 日志列表
            
        Returns:
            结构化后的日志列表
        """
        structured_logs = []
        
        for log in logs:
            try:
                structured_log = self.structure_log(log)
                structured_logs.append(structured_log)
            except Exception as e:
                logger.error(f"结构化单条日志失败: {e}")
                # 保留原始日志
                structured_logs.append(log)
        
        return structured_logs
    
    def _parse_message(self, message: str) -> Dict[str, Any]:
        """
        解析消息内容
        
        Args:
            message: 原始消息
            
        Returns:
            解析出的字段
        """
        if not message:
            return {}
        
        # 尝试解析JSON格式
        if self.log_patterns['json'].match(message.strip()):
            return self._parse_json_message(message)
        
        # 尝试解析标准日志格式
        for pattern_name, pattern in self.log_patterns.items():
            if pattern_name == 'json':
                continue
            
            match = pattern.match(message)
            if match:
                return self._parse_pattern_message(pattern_name, match)
        
        # 无法解析，返回空字典
        return {}
    
    def _parse_json_message(self, message: str) -> Dict[str, Any]:
        """
        解析JSON格式消息
        
        Args:
            message: JSON格式消息
            
        Returns:
            解析出的字段
        """
        try:
            data = json.loads(message)
            if isinstance(data, dict):
                return data
            return {}
        except json.JSONDecodeError:
            return {}
    
    def _parse_pattern_message(self, pattern_name: str, match) -> Dict[str, Any]:
        """
        根据模式解析消息
        
        Args:
            pattern_name: 模式名称
            match: 正则匹配结果
            
        Returns:
            解析出的字段
        """
        if pattern_name == 'standard':
            return {
                'timestamp': match.group(1),
                'level': match.group(2),
                'source': match.group(3),
                'message': match.group(4)
            }
        elif pattern_name == 'simple':
            return {
                'timestamp': match.group(1),
                'level': match.group(2),
                'message': match.group(3)
            }
        elif pattern_name == 'nginx':
            return {
                'remote_addr': match.group(1),
                'timestamp': match.group(2),
                'request': match.group(3),
                'status': int(match.group(4)),
                'bytes': int(match.group(5)),
                'referer': match.group(6),
                'user_agent': match.group(7)
            }
        elif pattern_name == 'apache':
            return {
                'remote_addr': match.group(1),
                'timestamp': match.group(2),
                'request': match.group(3),
                'status': int(match.group(4)),
                'bytes': int(match.group(5))
            }
        
        return {}
    
    def _normalize_fields(self, log_data: Dict[str, Any]) -> Dict[str, Any]:
        """
        标准化字段名称
        
        Args:
            log_data: 日志数据
            
        Returns:
            标准化后的日志数据
        """
        normalized_data = {}
        
        for standard_field, possible_names in self.field_mapping.items():
            for name in possible_names:
                if name in log_data:
                    normalized_data[standard_field] = log_data[name]
                    break
        
        # 保留其他字段
        for key, value in log_data.items():
            if key not in normalized_data:
                normalized_data[key] = value
        
        return normalized_data
    
    def _parse_timestamp_field(self, timestamp_value: Any) -> Optional[Dict[str, Any]]:
        """
        解析时间戳字段
        
        Args:
            timestamp_value: 时间戳值
            
        Returns:
            解析后的时间戳信息
        """
        try:
            if isinstance(timestamp_value, str):
                dt = parse_timestamp(timestamp_value)
            elif isinstance(timestamp_value, (int, float)):
                dt = parse_timestamp(timestamp_value)
            else:
                return None
            
            return {
                'datetime': dt,
                'iso_format': dt.isoformat(),
                'formatted': format_timestamp(dt),
                'year': dt.year,
                'month': dt.month,
                'day': dt.day,
                'hour': dt.hour,
                'minute': dt.minute,
                'second': dt.second,
                'weekday': dt.weekday()
            }
            
        except Exception as e:
            logger.error(f"解析时间戳失败: {e}")
            return None
    
    def _get_current_timestamp(self) -> float:
        """
        获取当前时间戳
        
        Returns:
            当前时间戳
        """
        import time
        return time.time()
    
    def add_log_pattern(self, name: str, pattern: str) -> None:
        """
        添加日志格式模式
        
        Args:
            name: 模式名称
            pattern: 正则表达式模式
        """
        try:
            compiled_pattern = re.compile(pattern)
            self.log_patterns[name] = compiled_pattern
            logger.info(f"添加日志模式: {name}")
        except Exception as e:
            logger.error(f"添加日志模式失败: {e}")
    
    def remove_log_pattern(self, name: str) -> bool:
        """
        移除日志格式模式
        
        Args:
            name: 模式名称
            
        Returns:
            是否成功移除
        """
        if name in self.log_patterns:
            del self.log_patterns[name]
            logger.info(f"移除日志模式: {name}")
            return True
        return False
    
    def add_field_mapping(self, standard_field: str, possible_names: List[str]) -> None:
        """
        添加字段映射
        
        Args:
            standard_field: 标准字段名
            possible_names: 可能的字段名列表
        """
        self.field_mapping[standard_field] = possible_names
        logger.info(f"添加字段映射: {standard_field} -> {possible_names}")
    
    def get_structure_stats(self) -> Dict[str, Any]:
        """
        获取结构化统计信息
        
        Returns:
            结构化统计信息
        """
        return {
            'log_patterns_count': len(self.log_patterns),
            'field_mapping_count': len(self.field_mapping),
            'log_patterns': list(self.log_patterns.keys()),
            'field_mappings': self.field_mapping
        }
    
    def extract_structured_fields(self, message: str) -> Dict[str, Any]:
        """
        从消息中提取结构化字段
        
        Args:
            message: 消息内容
            
        Returns:
            提取的结构化字段
        """
        return self._parse_message(message) 